package com.hp.gxw.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hp.gxw.constant.R;
import com.hp.gxw.entity.*;
import com.hp.gxw.exception.BusinessException;
import com.hp.gxw.mapper.SaleOrderMapper;
import com.hp.gxw.mapper.SettleOrderDetailNewMapper;
import com.hp.gxw.mapper.SettleOrderMasterNewMapper;
import com.hp.gxw.service.IProcessPriceOrderService;
import com.hp.gxw.service.ISaleOrderDetailsService;
import com.hp.gxw.service.ISaleOrderProcessService;
import com.hp.gxw.service.ISaleOrderService;
import com.hp.gxw.u8.EFWebService;
import com.hp.gxw.u8.U8ApiUtils;
import com.hp.gxw.u8.U8WebXMLResponseU8WebXMLResult;
import com.hp.gxw.u8.dto.U8ApiResultDto;
import com.hp.gxw.u8.dto.U8OrderDeleteParameter;
import com.hp.gxw.u8.xml.U8OrderDeleteXml;
import com.hp.gxw.utils.ShiroUtil;
import org.apache.axis.message.MessageElement;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author huangping
 * @since 2023-10-17
 */
@Service
public class SaleOrderServiceImpl extends ServiceImpl<SaleOrderMapper, SaleOrder> implements ISaleOrderService {

    @Autowired
    private ISaleOrderDetailsService iSaleOrderDetailsService;

    @Autowired
    private ISaleOrderProcessService iSaleOrderProcessService;

    @Autowired
    private IProcessPriceOrderService iProcessPriceOrderService;

    @Resource
    private SaleOrderMapper saleOrderMapper;

    @Resource
    private SettleOrderMasterNewMapper settleOrderMasterNewMapper;

    @Resource
    private SettleOrderDetailNewMapper settleOrderDetailNewMapper;

    @Value("${u8client.serviceId}")
    private String serviceId;

    @Value("${u8client.environment}")
    private String environment;

    @Autowired
    private EFWebService eFWebServiceLocator;

    @Autowired
    private U8ApiUtils u8ApiUtils;

    @Override
    @Transactional
    public void saveInfo(SaleOrder saleOrder, List<SaleOrderDetails> detailsList) throws Exception {
        save(saleOrder);
        for(SaleOrderDetails saleOrderDetails : detailsList){
            saleOrderDetails.setMasterId(saleOrder.getId());
            iSaleOrderDetailsService.save(saleOrderDetails);
//            saleOrderDetails.setMesId(saleOrderDetails.getId().toString());
//            iSaleOrderDetailsService.updateById(saleOrderDetails);
            List<SaleOrderProcess> processList = saleOrderDetails.getProcess();
            for(SaleOrderProcess saleOrderProcess : processList){
                saleOrderProcess.setDetailsId(String.valueOf(saleOrderDetails.getId()));
            }
            iSaleOrderProcessService.saveBatch(processList);
        }
    }

    @Override
    public List<SaleOrderProcess> getSettlementPrice(QueryWrapper<SaleOrder> ew) {
        return saleOrderMapper.getSettlementPrice(ew);
    }

    @Override
    public List<SaleOrderProcess> getSettlementPriceAdd(QueryWrapper<SaleOrder> ew) {
        return saleOrderMapper.getSettlementPriceAdd(ew);
    }

    @Override
    public Page<Map<String,Object>> getSaleReportPage(Page<Object> page, QueryWrapper<SaleOrder> ew) {
        return saleOrderMapper.getSaleReportPage(page,ew);
    }

    @Override
    public List<Map<String, Object>> getSaleReportList(QueryWrapper ew) {
        return saleOrderMapper.getSaleReportList(ew);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void processInfoPrice(String detailsId, String processId) {
        SaleOrderDetails orderDetails = iSaleOrderDetailsService.getById(detailsId);
        SaleOrder saleOrder = getById(orderDetails.getMasterId());
        SaleOrderProcess process = iSaleOrderProcessService.getById(processId);
        List<ProcessPriceOrder> list = iProcessPriceOrderService.list(Wrappers.lambdaQuery(ProcessPriceOrder.class)
                .eq(ProcessPriceOrder::getCustomerId, saleOrder.getCustomerCode())
                .eq(ProcessPriceOrder::getProductId, orderDetails.getCinvcode())
                .eq(ProcessPriceOrder::getOrderProcessCode, process.getOrderProcess())
        );
        if (!list.isEmpty()) {
            //如果存在就修改
            list.forEach(order -> {
                order.setOrderPrice(process.getIoritaxcost());
//                order.setPricingMethod(process.getPricingMethod());
            });
            iProcessPriceOrderService.updateBatchById(list);
        }else {
            //添加一条
            ProcessPriceOrder order = new ProcessPriceOrder();
            order.setCustomerId(saleOrder.getCustomerCode());
            order.setProductId(orderDetails.getCinvcode());
            order.setType(orderDetails.getType());
//            order.setPricingMethod(process.getPricingMethod());
            order.setOrderProcessCode(process.getOrderProcess());
            order.setExpectHours(process.getExpectHours());
            order.setOrderPrice(process.getIoritaxcost());
            order.setCreateUser(ShiroUtil.getUserId());
            order.setCreateTime(new Date());
            iProcessPriceOrderService.save(order);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(JSONObject json) {

        //判断内部订单号是否存在
        String orderNo = json.getString("orderNo");
        if (StringUtils.isEmpty(orderNo)){
            throw new RuntimeException("内部订单号未填写！");
        }
        long count = count(Wrappers.lambdaQuery(SaleOrder.class).eq(SaleOrder::getOrderNo, orderNo));
        if (count > 0){
            throw new RuntimeException("内部订单号已存在！");
        }
        SaleOrder saleOrder = new SaleOrder();
        saleOrder.setStatus(false);
        BeanUtil.copyProperties(json, saleOrder);
        Date createTime = json.getDate("createTime");
        saleOrder.setDdate(DateUtil.format(createTime, "yyyy-MM-dd HH:mm:ss"));
        saleOrder.setCustom(true);
        saleOrder.setCreateTime(new Date());
        save(saleOrder);

        JSONArray details = json.getJSONArray("details");
        for (Object detail : details) {
            JSONObject detailObj = (JSONObject) detail;
            saveDetails(detailObj, saleOrder);
        }

    }

    private void saveDetails(JSONObject detailObj, SaleOrder saleOrder) {
        //添加明细
        SaleOrderDetails orderDetails = new SaleOrderDetails();
        BeanUtil.copyProperties(detailObj, orderDetails);
        orderDetails.setMasterId(saleOrder.getId());
        orderDetails.setCompletFlag(false);
        iSaleOrderDetailsService.saveOrUpdate(orderDetails);
        orderDetails.setMesId(String.valueOf(orderDetails.getId()));
        iSaleOrderDetailsService.updateById(orderDetails);
        //获取明细对应的工序
        JSONArray process = detailObj.getJSONArray("process");
        for (Object pro : process) {
            extracted(pro, orderDetails);
        }
    }

    private void extracted(Object pro, SaleOrderDetails orderDetails) {
        SaleOrderProcess orderProcess = new SaleOrderProcess();
        BeanUtil.copyProperties(pro, orderProcess);
        orderProcess.setDetailsId(String.valueOf(orderDetails.getId()));
        iSaleOrderProcessService.saveOrUpdate(orderProcess);
        //判断工序是否存在
        processInfoPrice(String.valueOf(orderDetails.getId()),String.valueOf(orderProcess.getId()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void upd(JSONObject json) {

        String orderNo = json.getString("orderNo");
        SaleOrder saleOrder = getOne(Wrappers.lambdaQuery(SaleOrder.class).eq(SaleOrder::getOrderNo, orderNo));
        if (null == saleOrder){
            throw new RuntimeException("内部订单号不存在！");
        }
        BeanUtil.copyProperties(json, saleOrder);
        Date createTime = json.getDate("createTime");
        saleOrder.setDdate(DateUtil.format(createTime, "yyyy-MM-dd"));
        saleOrder.setDverifydate(DateUtil.format(createTime, "yyyy-MM-dd"));
        saleOrder.setDverifysystime(DateUtil.format(createTime, "yyyy-MM-dd HH:mm:ss"));
        saleOrder.setCustom(true);
        saleOrder.setCreateTime(new Date());
        //修改主表
        updateById(saleOrder);

        JSONArray details = json.getJSONArray("details");
        for (Object detail : details) {
            JSONObject detailObj = (JSONObject) detail;
            String detailId = detailObj.getString("id");
            saveDetails(detailObj, saleOrder);
            JSONArray process = detailObj.getJSONArray("process");
            SaleOrderDetails orderDetails = iSaleOrderDetailsService.getById(detailId);
            for (Object pro : process) {
                JSONObject pp = (JSONObject) pro;
                String ppId = pp.getString("id");
                if (!StringUtils.isEmpty(ppId)){
                    extracted(pp, orderDetails);
                }
            }
        }

    }

    @Override
    public Page<SaleOrder> listStat(Page<Object> objectPage, QueryWrapper<SaleOrder> ew) {
        return saleOrderMapper.listStat(objectPage,ew);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void close(String id) {
        SaleOrder saleOrder = saleOrderMapper.selectById(id);
        saleOrder.setStatus(true);
        saleOrderMapper.updateById(saleOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void priceNullify(String detailsId) {
        //校验是否结算
        Long l = settleOrderMasterNewMapper.selectCount(Wrappers.lambdaQuery(SettleOrderMasterNew.class)
                .eq(SettleOrderMasterNew::getSaleOrderDetailId, detailsId)
        );
        if(l > 0){
            throw new RuntimeException("该订单已结算，无法作废！");
        }
        SaleOrderDetails byId = iSaleOrderDetailsService.getById(detailsId);
        byId.setCompletFlag(false);
        byId.setAmount(null);
        long count = iSaleOrderDetailsService.count(Wrappers.lambdaQuery(SaleOrderDetails.class)
                .eq(SaleOrderDetails::getMasterId, byId.getMasterId())
                .eq(SaleOrderDetails::getCompletFlag, true)
        );
        if(count <= 0){
            SaleOrder saleOrder = saleOrderMapper.selectById(byId.getMasterId());
            saleOrder.setFixStatus(false);
            saleOrderMapper.updateById(saleOrder);
        }
        iSaleOrderDetailsService.updateById(byId);
        //删除U8销售订单
        U8OrderDeleteParameter u8OrderDeleteParameter = new U8OrderDeleteParameter();
        u8OrderDeleteParameter.setEfserverid(serviceId);
        u8OrderDeleteParameter.setEftype("17");
        u8OrderDeleteParameter.setEfid(byId.getErpId());
        u8OrderDeleteParameter.setEfcode(byId.getErpCode());
        R r = deleteU8Order(u8OrderDeleteParameter);
        if("500".equals(r.get("code").toString())){
            throw new BusinessException(r.get("msg").toString());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void settleNullify(String id) {
        SettleOrderMasterNew settleOrderMasterNew = settleOrderMasterNewMapper.selectById(id);
        settleOrderDetailNewMapper.delete(Wrappers.lambdaUpdate(SettleOrderDetailNew.class).in(SettleOrderDetailNew::getMasterId, settleOrderMasterNew.getId()));
        settleOrderMasterNewMapper.deleteById(settleOrderMasterNew.getId());
        //删除U8销售订单
        U8OrderDeleteParameter u8OrderDeleteParameter = new U8OrderDeleteParameter();
        u8OrderDeleteParameter.setEfserverid(serviceId);
        u8OrderDeleteParameter.setEftype("01");
        u8OrderDeleteParameter.setEfid(settleOrderMasterNew.getErpId());
        u8OrderDeleteParameter.setEfcode(settleOrderMasterNew.getErpCode());
        R r = deleteU8Order(u8OrderDeleteParameter);
        if("500".equals(r.get("code").toString())){
            throw new BusinessException(r.get("msg").toString());
        }
    }

    public R deleteU8Order(U8OrderDeleteParameter u8OrderDeleteParameter) {
        u8OrderDeleteParameter.setProc("query");
        if(environment.equals("pro")){
            U8WebXMLResponseU8WebXMLResult u8WebXML = null;
            try {
                u8WebXML = eFWebServiceLocator.getEFWebServiceSoap().u8WebXML(U8OrderDeleteXml.createXML(u8OrderDeleteParameter));
                //解析返回结果
                MessageElement[] unVerifyData = u8WebXML.get_any();
                if("1".equals(unVerifyData[0].getAttribute("succeed"))) {
                    return R.error("请先删除U8的相应单据【"+u8OrderDeleteParameter.getEfcode()+"】");
                }
//                u8OrderDeleteParameter.setProc("delete");
//                u8WebXML = eFWebServiceLocator.getEFWebServiceSoap().u8WebXML(U8OrderDeleteXml.createXML(u8OrderDeleteParameter));
//                //解析返回结果
//                MessageElement[] delData = u8WebXML.get_any();
//                if("0".equals(delData[0].getAttribute("succeed").toString())) {
//                    return R.error("接口异常"+delData[0].getAttribute("dsc").toString());
//                }

//                //读取XML文件，获得document对象
//                u8WebXML = eFWebServiceLocator.getEFWebServiceSoap().u8WebXML(unVerifyData[0].toString().replace("proc=\"query\"", "proc=\"delete\""));
//                unVerifyData = u8WebXML.get_any();
//                System.out.println(unVerifyData[0].getAttribute("dsc").toString());
//                if("0".equals(unVerifyData[0].getAttribute("succeed").toString())) {
//                    return R.error(unVerifyData[0].getAttribute("dsc").toString());
//                }
            }  catch (Exception e) {
                e.printStackTrace();
                return R.error("接口异常");
            }
        }else if(environment.equals("dev")){
            try {
                U8ApiResultDto unVerifyResultDto = u8ApiUtils.httpRequest(U8OrderDeleteXml.createXML(u8OrderDeleteParameter).split("\n")[1]);
                if(unVerifyResultDto == null || "1".equals(unVerifyResultDto.getCode())) {
                    return R.error("请先删除U8的相应单据【"+u8OrderDeleteParameter.getEfcode()+"】");
                }
//                if(unVerifyResultDto == null || "0".equals(unVerifyResultDto.getCode())) {
//                    return R.error(unVerifyResultDto==null?"接口异常":unVerifyResultDto.getMsg());
//                }
//                unVerifyResultDto = u8ApiUtils.httpRequest(unVerifyResultDto.getXml().replace("proc=\"query\"", "proc=\"delete\""));
//                if(unVerifyResultDto == null || "0".equals(unVerifyResultDto.getCode())) {
//                    return R.error(unVerifyResultDto==null?"接口异常":unVerifyResultDto.getMsg());
//                }
//                u8OrderDeleteParameter.setProc("delete");
//                U8ApiResultDto delResultDto = u8ApiUtils.httpRequest(U8OrderDeleteXml.createXML(u8OrderDeleteParameter).split("\n")[1]);
//                if(delResultDto == null || "0".equals(delResultDto.getCode())) {
//                    return R.error(delResultDto==null?"接口异常":delResultDto.getMsg());
//                }
            }catch (Exception e){
                e.printStackTrace();
                return R.error("接口异常");
            }
        }
        return R.ok();
    }
}
